// Copyright 2022 a.o.smith ALL Rights Reserved
package com.liuxinlong.modules.system.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import com.liuxinlong.modules.dao.MenuDao;
import com.liuxinlong.modules.entity.UserRoleRelation;
import com.liuxinlong.utils.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.liuxinlong.common.SnowFlake;
import com.liuxinlong.modules.dao.RoleRightDao;
import com.liuxinlong.modules.entity.RoleRight;
import com.liuxinlong.modules.system.service.RoleRightService;

import lombok.extern.slf4j.Slf4j;

/**
 * 用户角色权限service实现
 *
 * @author liuxinlong@hotwater.com.cn
 * @version 1.0.0
 * @since 2022年2月16日
 */
@Service
@Slf4j
public class RoleRightServiceImpl implements RoleRightService {

    @Autowired
    private RoleRightDao roleRightDao;

    @Autowired
    private MenuDao menuDao;

    @Override
    public void updateRoleRight(String roleId, List<String> rightList) {
        roleRightDao.deleteByRoleId(roleId);
        List<RoleRight> roleRights = new ArrayList<>(rightList.size());
        for (String menu : rightList) {
            RoleRight roleRight = new RoleRight();
            roleRight.setId(SnowFlake.nextIdStr());
            roleRight.setRole(roleId);
            roleRight.setMenuId(menu);
            roleRights.add(roleRight);
        }
        roleRightDao.batchAddRoleRight(roleRights);
    }

    @Override
    public Map<String, Object> queryRoleRightNames(String userId) {
        List<RoleRight> roleRightList = roleRightDao.queryUserRoleRightList(userId);
        Map<String, Map<String, String>> menuMap = menuDao.getMenuMap();
        List<String> authorityList = new ArrayList<>();
        List<String> buttonAuthorityList = new ArrayList<>();
        Set<String> menuSet = new HashSet<>();
        for (RoleRight roleRight : roleRightList) {
            if (ObjectUtils.isEmpty(roleRight)) {
                continue;
            }
            String menuId = roleRight.getMenuId();
            if (StringUtils.isEmpty(menuId)) {
                continue;
            }
            Map<String, String> menuInfo = menuMap.get(menuId);
            if (ObjectUtils.isEmpty(menuInfo)) {
                continue;
            }
            if (StringUtils.equals(String.valueOf(menuInfo.get("rightType")), "1")) {
                buttonAuthorityList.add(menuInfo.get("rightCode"));
            }
            generateMenu(menuId, menuMap, menuSet);
        }
        Map<String, Object> resultMap = new HashMap<>();
        authorityList.addAll(menuSet);
        resultMap.put("authority", authorityList);
        resultMap.put("buttonAuthority", buttonAuthorityList);
        return resultMap;
    }

    @Override
    public boolean checkPermission(List<UserRoleRelation> roleRelationList, String url) {
        if (ObjectUtils.isEmpty(roleRelationList)) {
            return false;
        }
        List<String> roleIdList = roleRelationList.stream().map(UserRoleRelation::getRoleId).collect(Collectors.toList());
        List<RoleRight> roleRightList = roleRightDao.queryRoleRightInfo(roleIdList, url);
        return !ObjectUtils.isEmpty(roleRightList);
    }

    @Override
    public List<String> queryRoleRight(String roleId) {
        List<RoleRight> roleRightList = roleRightDao.queryRoleRightList(roleId);
//        List<String> newList = new ArrayList<>();
        List<String> newList = roleRightList.stream().map(RoleRight::getMenuId).collect(Collectors.toList());
//        Map<String, Map<String, String>> menuMap = menuDao.getMenuMap();
//        Set<String> rightSet = new HashSet<>();
//        for (RoleRight right: roleRightList) {
//            loopMenuId(right.getMenuId(),menuMap,rightSet);
//        }
//        newList.addAll(rightSet);
        return newList;
    }

    private Set<String> generateMenu(String menuId, Map<String, Map<String, String>> menuMap, Set<String> menuSet) {
        if (StringUtils.equals(menuId, "0")) {
            return menuSet;
        }
        Map<String, String> menuInfo = menuMap.get(menuId);
        if (ObjectUtils.isEmpty(menuInfo)) {
            return menuSet;
        }
        if (!StringUtils.equals(String.valueOf(menuInfo.get("rightType")), "1")) {
            menuSet.add(menuInfo.get("rightCode"));
        }
        menuSet = generateMenu(menuInfo.get("parentId"), menuMap, menuSet);
        return menuSet;
    }

    private Set<String> loopMenuId(String menuId, Map<String, Map<String, String>> menuMap, Set<String> menuSet) {
        if (StringUtils.equals(menuId, "0")) {
            return menuSet;
        }
        Map<String, String> menuInfo = menuMap.get(menuId);
        if (ObjectUtils.isEmpty(menuInfo)) {
            return menuSet;
        }
        menuSet.add(menuId);
        menuSet = loopMenuId(menuInfo.get("parentId"), menuMap, menuSet);
        return menuSet;
    }
}
